package com.smart.milvus.model.metadata;

import com.smart.milvus.base.DynamicCollectionHandler;
import com.smart.milvus.bean.GlobalConfig;
import com.smart.milvus.bean.MilvusModel;
import com.smart.milvus.util.StringUtils;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Data
public class CollectionDefinition {
    /**
     * 指定数据库，若未指定，则使用默认的
     */
    private String database;
    /**
     * 实体类型
     */
    private Class<?> entityType;
    /**
     * 前缀
     */
    private String prefix;
    /**
     * 格式
     */
    private String format;
    /**
     * 表名称
     */
    private String name;
    /**
     * 默认名称
     */
    private String defaultName;
    /**
     * 表描述
     */
    private String description;
    /**
     * 表主键ID 字段名
     */
    private String keyColumn;
    /**
     * 表主键ID 属性名
     */
    private String keyProperty;
    /**
     * 表主键字段
     */
    private Field keyField;
    /**
     * 是否开启下划线转驼峰
     * <p>
     * 未注解指定字段名的情况下,用于自动从 property 推算 column 的命名
     */
    private boolean underCamel = true;
    /**
     * 表字段信息列表
     */
    private List<ColumnDefinition> columns;
    /**
     * 集合处理程序
     */
    private DynamicCollectionHandler collectionHandler;

    /**
     * @param entityType 实体类型
     */
    public CollectionDefinition(Class<?> entityType) {
        this.entityType = entityType;
    }

    public ColumnDefinition getPrimaryColumn() {
        for (ColumnDefinition columnDefinition : columns) {
            if (columnDefinition.isPrimary()) {
                return columnDefinition;
            }
        }
        return null;
    }

    public List<ColumnDefinition> getVectorColumns() {
        List<ColumnDefinition> list = new ArrayList<>();
        for (ColumnDefinition columnDefinition : columns) {
            if (Boolean.TRUE.equals(columnDefinition.vectorColumn())) {
                list.add(columnDefinition);
            }
        }
        if (collectionHandler == null) {
            return list;
        }
        Field[] fields = new Field[list.size()];
        for (int i = 0; i < list.size(); i++) {
            ColumnDefinition columnDefinition = list.get(i);
            fields[i] = columnDefinition.getField();
        }
        int[] ints = collectionHandler.vectorDimension((Class<? extends MilvusModel<?>>) entityType, fields);
        for (int i = 0; i < list.size(); i++) {
            ColumnDefinition columnDefinition = list.get(i);
            columnDefinition.setVectorDimension(ints[i]);
        }
        return list;
    }

    public String getDatabase() {
        String db = database;
        if (collectionHandler != null) {
            db = collectionHandler.dynamicDatabaseName((Class<? extends MilvusModel<?>>) entityType);
        }
        if (StringUtils.isBlank(db)) {
            db = GlobalConfig.INSTANCE.getMilvusProperties().getDatabase();
        }
        return db;
    }

    public String getName() {
        String cname = name;
        if (collectionHandler != null) {
            cname = collectionHandler.dynamicCollectionName((Class<? extends MilvusModel<?>>) entityType, prefix, format, underCamel);
        }
        if (StringUtils.isBlank(cname)) {
            if (StringUtils.isNotBlank(prefix)) {
                cname = prefix + defaultName;
            }
            if (StringUtils.isNotBlank(format)) {
                cname = String.format(format, cname);
            }
        }
        return cname;
    }

    /**
     * 是否有主键
     *
     * @return 是否有
     */
    public boolean havePK() {
        return StringUtils.isNotBlank(keyColumn);
    }

    public List<ColumnDefinition> getFieldList() {
        return Collections.unmodifiableList(columns);
    }

    public ColumnDefinition getColumnByColumnName(String columnName) {
        for (ColumnDefinition columnDefinition : columns) {
            if (columnDefinition.getName().equals(columnName)) {
                return columnDefinition;
            }
        }
        return null;
    }
}
